/*
 * @Author: wangke
 * @Date: 2025-03-13 00:03:09
 * @LastEditors: wangke
 * @LastEditTime: 2025-04-30 00:07:58
 * 
 */

#include "Sonix.h"
#include <Wire.h>
#include "BspOid.h"
#include <Arduino.h>
#include "Common.h"
#include "App_I2S.h"
// #define SONIX_SDA 21
// #define SONIX_SCL 22

#define EEPROM_ADDRESS 0x50
#define EEPROM_SIZE 1024
#define SONIX_ADDRESS 0x55

#define Bsp_DelayMs(x) delay(x)
#if FUNC_OID_EN_DEBOUNCE
typedef struct
{
    uint16_t usTimer;                                   /**< This timer is to check oid idle, if there is no data recived for a long time, it means oid idle and oid up */
    uint16_t usRstFlag;                                 /**< This flag shows there is reset request or not */
    uint16_t usInvalidCnt;                              /**< This counter is to check oid up, if there is to many invalid data recived, it means oid up */
    uint16_t usWrPos;                                   /**< Write position of ullaDebArray[] next time */
    uint64_t ullOldIndex;                               /**< Last recived index in the peroid of oid down */
    uint64_t ullaDebArray[ FUNC_OID_DEB_INDEX_CNT ];    /**< This array saved index recived for debounce */
} OidDebInfo_t;
#endif
#if FUNC_OID_EN_DEBOUNCE
    static OidDebInfo_t s_tOidDebInfo;
#endif
uint64_t ullIndex;
BSP_OID_TYPE_E eType;
/**
  * @brief  Initialize oid module.
  * @retval 0: Ok; Other: Fail
  */
 int32_t Func_Oid_Init( void )
 {
     int32_t iRes;
     uint16_t i;
     BSP_OID_VER_E eVersion = BSP_OID_VER_UNKNOW;
     
     // Oid device start up
     i = 3;
     Bsp_Oid_Init();
 #if BSP_OID_USE_NRST
     Bsp_Oid_LeaveReset();
 #endif
     while( i )
     {
         iRes = Bsp_Oid_StartUp( FUNC_OID_STARTUP_FORMT );
         if( iRes == SONIX_APP_OK )
         {
             break;
         }
         
         i--;
 #if BSP_OID_USE_NRST
         Bsp_Oid_Init();
         Bsp_Oid_EnterReset();
 #endif
         Bsp_DelayMs( 10 );
 #if BSP_OID_USE_NRST
         Bsp_Oid_LeaveReset();
 #endif
     }
     
     // Return if failed
     if( iRes != SONIX_APP_OK )
     {
         if( Bsp_Oid_SendCmd( 0x28 ) != SONIX_APP_OK )
         {
             return SONIX_APP_ERROR;
         }
     }
     
     // Check version
     i = 3;
     Bsp_DelayMs( 10 );
     while( i )
     {
         if( Bsp_Oid_GetRomVer( &eVersion ) == SONIX_APP_OK )
         {
             break;
         }
         
         i--;
         Bsp_DelayMs( 120 );
     }
     
     // Set new format
     if( ( eVersion == BSP_OID_VER_ROM008 ) || ( eVersion == BSP_OID_VER_ROM009 ) )
     {
         
 #if FUNC_OID_ONLY_TYPE_EN
         i = 3;
         Bsp_DelayMs( 10 );
         while( i )
         {
             if( Bsp_Oid_WriteReg( 0x0D40 , FUNC_OID_ONLY_TYPE ) == SONIX_APP_OK )
             {
                 break;
             }
             
             i--;
             Bsp_DelayMs( 120 );
         }
 #endif
         
         i = 3;
         Bsp_DelayMs( 10 );
         while( i )
         {
             if( Bsp_Oid_SendCmd( 0x2C ) == SONIX_APP_OK )
             {
                 break;
             }
             
             i--;
             Bsp_DelayMs( 10 );
         }
     }
     
     // Set 50 fps
     i = 3;
     Bsp_DelayMs( 10 );
     while( i )
     {
         if( Bsp_Oid_SendCmd( 0x27 ) == SONIX_APP_OK )
         {
             break;
         }
         
         i--;
         Bsp_DelayMs( 10 );
     }
     
 #if FUNC_OID_EN_DEBOUNCE
     // Set continuation mode at last
     i = 3;
     Bsp_DelayMs( 10 );
     while( i )
     {
         iRes = Bsp_Oid_SendCmd( 0x40 );
         if( iRes == SONIX_APP_OK )
         {
             break;
         }
         
         i--;
         Bsp_DelayMs( 10 );
     }
     
     // Initialize structure
     memset( &s_tOidDebInfo , 0 , sizeof( s_tOidDebInfo ) );
     s_tOidDebInfo.ullOldIndex = ( uint64_t ) -1;
     s_tOidDebInfo.ullaDebArray[ FUNC_OID_DEB_INDEX_CNT - 1 ] = ( uint64_t ) -1;
     
     // Return if failed
     if( iRes != SONIX_APP_OK )
     {
         return SONIX_APP_ERROR;
     }
 #endif
     
     return SONIX_APP_OK;
 }
 
/**
  * @brief  This function is to get valid oid index.
  * @note   Call this function frequently, to check and recive index timely
  * @param  uint64_t* pullIndex: pointer to save oid index
  *         BSP_OID_TYPE_E* peType: the type of valid index
  * @retval 0: Ok; Other: Fail/No index ready
  */
uint32_t* pulIndex;
Bsp_Oid_Data_t tOidData;
 int32_t Func_Oid_GetIndex( uint64_t* pullIndex , BSP_OID_TYPE_E* peType )
 {
    //  uint32_t* pulIndex;
    //  Bsp_Oid_Data_t tOidData;
     
     // Check and read oid data
     if( Bsp_Oid_GetData( &tOidData ) != SONIX_APP_OK )
     {
         return SONIX_APP_ERROR_NOTRDY;
     }
     
 #if FUNC_OID_EN_DEBOUNCE == 0
     // Check general index
     if( ( tOidData.eType >= BSP_OID_TYPE_2GEN ) && ( tOidData.eType <= BSP_OID_TYPE_OLDGEN ) )
     {
         // Send out general index
         pulIndex = ( uint32_t* ) pullIndex;
         *pulIndex = tOidData.ulData1;
         pulIndex++;
         *pulIndex = tOidData.ulData2;
         *peType = tOidData.eType;
         return SONIX_APP_OK;
     }
     
     // Not general index
     return SONIX_APP_ERROR_INVALID;
     
 #else
     // Check reset first
     if( s_tOidDebInfo.usRstFlag != 0 )
     {
         // Reset debounce
         memset( &s_tOidDebInfo , 0 , sizeof( s_tOidDebInfo ) );
         s_tOidDebInfo.ullOldIndex = ( uint64_t ) -1;
         s_tOidDebInfo.ullaDebArray[ FUNC_OID_DEB_INDEX_CNT - 1 ] = ( uint64_t ) -1;
     }
     
     // Check general index
     if( ( tOidData.eType < BSP_OID_TYPE_2GEN ) || ( tOidData.eType > BSP_OID_TYPE_OLDGEN ) )
     {
         // Not general index
         tOidData.ulData1 = ( uint32_t ) -1;
         tOidData.ulData2 = ( uint32_t ) -1;
     }
 
     // Save index for debounce
     pulIndex = ( uint32_t* ) s_tOidDebInfo.ullaDebArray;
     pulIndex += s_tOidDebInfo.usWrPos * 2;
     *pulIndex = tOidData.ulData1;
     pulIndex ++;
     *pulIndex = tOidData.ulData2;
     s_tOidDebInfo.usWrPos++;
     if( s_tOidDebInfo.usWrPos >= FUNC_OID_DEB_INDEX_CNT )
     {
         // Loop fifo
         s_tOidDebInfo.usWrPos = 0;
     }
     
     // Check valid, and reset timer as recived data
     s_tOidDebInfo.usTimer = FUNC_OID_DEB_TIMER_CNT;
     if( tOidData.eType < BSP_OID_TYPE_2GEN )
     {
         // Increase invalid counter
         s_tOidDebInfo.usInvalidCnt++;
         if( s_tOidDebInfo.usInvalidCnt >= FUNC_OID_DEB_INVALID_CNT )
         {
             // Counter up to max, means oid up, reset debounce
             memset( &s_tOidDebInfo , 0 , sizeof( s_tOidDebInfo ) );
             s_tOidDebInfo.ullOldIndex = ( uint64_t ) -1;
             s_tOidDebInfo.ullaDebArray[ FUNC_OID_DEB_INDEX_CNT - 1 ] = ( uint64_t ) -1;
         }
         
         return SONIX_APP_ERROR_INVALID;
     }
     
     // Rx valid, reset invalid counter, and compare saved data
     s_tOidDebInfo.usInvalidCnt = 0;
     for( uint16_t i = 0; i < ( FUNC_OID_DEB_INDEX_CNT - 1 ); i++ )
     {
         if( s_tOidDebInfo.ullaDebArray[ i ] != s_tOidDebInfo.ullaDebArray[ i + 1 ] )
         {
             // Saved data are not same
             return SONIX_APP_ERROR_NOTRDY;
         }
     }
     
     // Same index, check has recived in the peroid of oid down
     if( s_tOidDebInfo.ullaDebArray[ 0 ] == s_tOidDebInfo.ullOldIndex )
     {
         // Allready recived
         return SONIX_APP_ERROR_NOTRDY;
     }
     
     // New index, check if general code
     if( s_tOidDebInfo.ullaDebArray[ 0 ] == ( uint64_t )  -1 )
     {
         // Not general code
         return SONIX_APP_ERROR_NOTRDY;
     }
     
     // New index, send out and update saved old index for compare next time
     *pullIndex = s_tOidDebInfo.ullaDebArray[ 0 ];
     s_tOidDebInfo.ullOldIndex = s_tOidDebInfo.ullaDebArray[ 0 ];
     *peType = tOidData.eType;
     return SONIX_APP_OK;
     
 #endif
 }
uint8_t Sonix_ReceiveGeneralIndex()
{
    // if( Func_Oid_GetIndex( &ullIndex , &eType ) == SONIX_APP_OK )
    // {
    //     char buffer[64];
    //     snprintf(buffer, sizeof(buffer),"Rx Index: %u , %u\r\n" , ( uint32_t ) ullIndex , eType );
    //     Serial1.println(buffer);
    // }
    if( Bsp_Oid_CheckRx() != false )
    {
        if( Bsp_Oid_GetData( &tOidData ) == SONIX_APP_OK )
        {
            if(tOidData.eType == 6)
            { 
                printfme( "Rx Index: %u , 0x%08X , 0x%08X , %u\r\n" , tOidData.eType , tOidData.ulData1 , tOidData.ulData2 , tOidData.ulAngle );

                if(tOidData.ulData1 == 0x00002710)
                { play_SD_video("/10000.wav"); }
                if(tOidData.ulData1 == 0x00002711)
                { play_SD_video("/10001.wav"); }
                if(tOidData.ulData1 == 0x00002712)
                { play_SD_video("/10002.wav"); }
                if(tOidData.ulData1 == 0x00002713)
                { play_SD_video("/10003.wav"); }
                if(tOidData.ulData1 == 0x00002714)
                { play_SD_video("/10004.wav"); }
                if(tOidData.ulData1 == 0x00002715)
                { play_SD_video("/10005.wav"); }

                return 1;
            }else{
                return 0;
            }
        }
    }else{
        return 0;
    }
    
    return 0;
}


